-------------------------------------------------------------------------------
---! CREATE TABLE TO HOLD CMD
-------------------------------------------------------------------------------
local process_cmd_map = {}

-------------------------------------------------------------------------------
---! CREATE TABLE TO COUNT CMD
-------------------------------------------------------------------------------
local process_cmd_stat = {}

-------------------------------------------------------------------------------
---! 对外接口
-------------------------------------------------------------------------------
COMMAND_D = {}

function COMMAND_D:process_command(userOb, MsgType, MsgData, size)
    local cmd = process_cmd_map[MsgType]
    if not cmd then
        spdlog.error("cmd", string.format("not found request command [%s]", MsgType))
        return
    end

    local func = cmd.func
    if not func then
        spdlog.error("cmd", string.format("not func is not function [%s]", MsgType))
        return
    end

    ---! 记录当前指令处理时间
    userOb:set_temp("command_time", os.time())

    ---! 优先尝试更新玩家数据
    userOb:update_data()

    ---! 而后尝试调用指令回调
    local tick = os.clock()
    xpcall(func, error_traceback, userOb, MsgData)
    local cost = os.clock() - tick

    local cmd_stat = process_cmd_stat[MsgType]
    if not cmd_stat then
        process_cmd_stat[MsgType] = { cost = cost, count = 1, size=size }
    else
        cmd_stat.count = (cmd_stat.count or 0) + 1
        cmd_stat.cost = (cmd_stat.cost or 0) + cost
        cmd_stat.size = (cmd_stat.size or 0) + size
    end
end

function COMMAND_D:register_command(cmd, func)
    process_cmd_map[cmd] = { func = func, }
end

function COMMAND_D:report_command()
    local summary = {}
    for cmd_type, cmd_stat in pairs(process_cmd_stat) do
        local stat = { cmd_type = cmd_type, count = cmd_stat.count, size=cmd_stat.size,
            per_size=cmd_stat.size / cmd_stat.count, total_cost = cmd_stat.cost, per_cost = cmd_stat.cost / cmd_stat.count, }
        table.insert(summary, stat)
    end
    table.sort(summary, function(a, b) return a.per_cost > b.per_cost end)

    print("start report_command >>> ")
    for _, stat in ipairs(summary) do
        print(string.format("%-10s : count = %10s, size = %10s, per_size = %10s, total_cost = %20s, per_cost = %20s",
            stat.cmd_type, stat.count, stat.size, stat.per_size, stat.total_cost, stat.per_cost))
    end
    print("end report_command.")
end

function COMMAND_D:timer_report()
    TIMER_D:start_timer(300, function()
        COMMAND_D:report_command()
    end)
end

register_post_init(function()
    ---! 默认自动启动
    COMMAND_D:timer_report()
end)
